<?php

namespace App\Ext\WeChat;

use App\Ext\Wechat\Common;

class Oauth
{
    /**
     * 引导用户进入授权页面同意授权 获取 code
     *
     * @param $appID # 第三方用户唯一凭证
     * @param $redirectURI # 授权后重定向的回调链接地址 请使用urlencode对链接进行处理
     * @param string $scope # 应用授权作用域 snsapi_base （不弹出授权页面，直接跳转，只能获取用户openid），snsapi_userinfo （弹出授权页面，可通过openid拿到昵称、性别、所在地。并且，即使在未关注的情况下，只要用户授权，也能获取其信息）
     * @param null $state # 重定向后会带上state参数，开发者可以填写a-zA-Z0-9的参数值，最多128字节
     * @return string
     */
    public static function code($appID, $redirectURI, $scope = 'snsapi_base', $state = null)
    {
        $redirectURI = urlencode($redirectURI);
        $url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' . $appID . '&redirect_uri=' . $redirectURI . '&response_type=code&scope=' . $scope . '&state=' . $state . '#wechat_redirect';
        return $url;
    }

    /**
     * 通过 code 换取网页授权 access_token（与基础支持中的 access_token 不同）
     * @param $appid 第三方用户唯一凭证
     * @param $secret 第三方用户唯一凭证密钥 appsecret
     * @param $code 引导用户进入授权页面同意授权后获取的 code
     * @return bool
     * 正确时返回的JSON数据包如下：
     * {
     *     "access_token":"ACCESS_TOKEN", # 网页授权接口调用凭证，注意：此 access_token 与基础支持的 access_token 不同 示例：OezXcEiiBSKSxW0eoylIeH24MzR6QFiao-MpWLIYDiNr6aLMAT9UNumXHJvhj83Pd_DsLWF12DUr4aU2iF1k7U4L2k33aa7TNZDbzdZIdNVF9lQoO2AyE6IYYaDotM_J3r05FRvtMlFBIqtZWVfcgg
     *     "expires_in":7200, # access_token接口调用凭证超时时间，单位（秒）
     *     "refresh_token":"REFRESH_TOKEN", # 用户刷新access_token 示例: OezXcEiiBSKSxW0eoylIeH24MzR6QFiao-MpWLIYDiNr6aLMAT9UNumXHJvhj83PBd4FKP6X653u8lnEI9qPsuAd5V1LosxsAcWs6ZaAi45Gvuhmun7fMZZdHpwhI1kJU5CgjHi5MAFZrFgQx-Y5jQ
     *     "openid":"OPENID", # 用户唯一标识，请注意，在未关注公众号时，用户访问公众号的网页，也会产生一个用户和公众号唯一的OpenID 示例：oicL-s-7L4EJkbIk_4i1Epaps0CU
     *     "scope":"SCOPE" # 用户授权的作用域，使用逗号（,）分隔 示例：snsapi_userinfo
     * }
     * 错误时微信会返回JSON数据包如下（示例为Code无效错误）:
     * {"errcode":40029,"errmsg":"invalid code"}
     */
    public static function authToken($appid, $secret, $code)
    {
        $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $appid . '&secret=' . $secret . '&code=' . $code . '&grant_type=authorization_code';
        $callback = Common::get($url);
        $callback = json_decode($callback);
        if (empty($callback->errcode)) {
            return $callback;
        } else {
            die('wechat error: [' . $callback->errcode . '] ' . $callback->errmsg);
        }
        return false;
    }

    /**
     * 刷新 access_token（如果需要）
     * @param $appid 公众号的唯一标识
     * @param $refreshToken 填写通过 access_token 获取到的 refresh_token 参数
     * @return bool
     * 正确时返回的JSON数据包如下：
     * {
     *     "access_token":"ACCESS_TOKEN", # 网页授权接口调用凭证，注意：此 access_token 与基础支持的 access_token 不同
     *     "expires_in":7200, # access_token 接口调用凭证超时时间，单位（秒）
     *     "refresh_token":"REFRESH_TOKEN", # 用户刷新 access_token
     *     "openid":"OPENID", # 用户唯一标识
     *     "scope":"SCOPE" # 用户授权的作用域，使用逗号（,）分隔
     * }
     * 错误时微信会返回JSON数据包如下（示例为 Code 无效错误）:
     * {"errcode":40029,"errmsg":"invalid code"}
     */
    public static function refershToken($appid, $refreshToken)
    {
        $url = 'https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=' . $appid . '&grant_type=refresh_token&refresh_token=' . $refreshToken;
        $callback = Common::get($url);
        $callback = json_decode($callback);
        if (empty($callback->errcode)) {
            return $callback;
        } else {
            die('wechat error: [' . $callback->errcode . '] ' . $callback->errmsg);
        }
        return false;
    }

    /**
     * 检验网页授权凭证 access_token 是否有效
     * @param $token 网页授权接口调用凭证，注意：此 access_token 与基础支持的 access_token 不同
     * @param $openID 用户的唯一标识
     * @return bool
     * 正确时的Json返回结果：{ "errcode":0,"errmsg":"ok"}
     * 错误时的Json返回示例：{ "errcode":40003,"errmsg":"invalid openid"}
     */
    public static function checkAuthToken($token, $openID)
    {
        $url = 'https://api.weixin.qq.com/sns/auth?access_token=' . $token . '&openid=' . $openID;
        $callback = Common::get($url);
        $callback = json_decode($callback);
        if (empty($callback->errcode)) {
            return $callback;
        } else {
            die('wechat error: [' . $callback->errcode . '] ' . $callback->errmsg);
        }
        return false;
    }

    /**
     * 拉取用户信息(需scope为 snsapi_userinfo)
     * @param $token 网页授权接口调用凭证 注意：此access_token与基础支持的access_token不同
     * @param $openID
     * @param string $lang
     * @return bool
     */
    public static function userInfo($token, $openID, $lang = 'zh_CN')
    {
        $url = 'https://api.weixin.qq.com/sns/userinfo?access_token=' . $token . '&openid=' . $openID . '&lang=' . $lang;
        $callback = Common::get($url);
        $callback = json_decode($callback);
        if (empty($callback->errcode)) {
            return $callback;
        } else {
            die('wechat error: [' . $callback->errcode . '] ' . $callback->errmsg);
        }
        return false;
    }
}